﻿using System;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

namespace ParticlePlayground
{
	// Token: 0x0200015D RID: 349
	public class PlaygroundQueue<T> : IDisposable where T : class
	{
		// Token: 0x0600080B RID: 2059 RVA: 0x0002F730 File Offset: 0x0002D930
		public PlaygroundQueue(int workerCount, Action<T> dequeueAction)
		{
			this._dequeueAction = dequeueAction;
			this._workers = new List<Thread>(workerCount);
			for (int i = 0; i < workerCount; i++)
			{
				Thread thread = new Thread(new ThreadStart(this.Consume))
				{
					IsBackground = true,
					Name = string.Format("PlaygroundQueue worker {0}", i)
				};
				this._workers.Add(thread);
				thread.Start();
			}
		}

		// Token: 0x0600080C RID: 2060 RVA: 0x0002F7C4 File Offset: 0x0002D9C4
		public virtual bool HasPool()
		{
			return this._workers.Count > 0;
		}

		// Token: 0x0600080D RID: 2061 RVA: 0x0002F7D4 File Offset: 0x0002D9D4
		public virtual bool HasTasks()
		{
			return this._taskQueue.Count > 0;
		}

		// Token: 0x0600080E RID: 2062 RVA: 0x0002F7E4 File Offset: 0x0002D9E4
		public virtual int ThreadPoolCount()
		{
			return this._workers.Count;
		}

		// Token: 0x0600080F RID: 2063 RVA: 0x0002F7F4 File Offset: 0x0002D9F4
		public virtual int TaskCount()
		{
			return this._taskQueue.Count;
		}

		// Token: 0x06000810 RID: 2064 RVA: 0x0002F804 File Offset: 0x0002DA04
		public virtual void SetThreadPool(int amount)
		{
			if (amount == this._workers.Count)
			{
				return;
			}
			amount = Mathf.Clamp(amount, 1, 128);
			if (amount > this._workers.Count)
			{
				for (int i = this._workers.Count; i < amount; i++)
				{
					Thread thread = new Thread(new ThreadStart(this.Consume))
					{
						IsBackground = true,
						Name = string.Format("PlaygroundQueue worker {0}", i)
					};
					this._workers.Add(thread);
					thread.Start();
				}
			}
			else
			{
				this.Dispose();
				this._workers = new List<Thread>(amount);
				for (int j = 0; j < amount; j++)
				{
					Thread thread2 = new Thread(new ThreadStart(this.Consume))
					{
						IsBackground = true,
						Name = string.Format("PlaygroundQueue worker {0}", j)
					};
					this._workers.Add(thread2);
					thread2.Start();
				}
			}
		}

		// Token: 0x06000811 RID: 2065 RVA: 0x0002F918 File Offset: 0x0002DB18
		public virtual void EnqueueTask(T task)
		{
			object locker = this._locker;
			lock (locker)
			{
				this._taskQueue.Enqueue(task);
				Monitor.Pulse(this._locker);
			}
		}

		// Token: 0x06000812 RID: 2066 RVA: 0x0002F968 File Offset: 0x0002DB68
		public virtual void Consume()
		{
			for (;;)
			{
				object locker = this._locker;
				T t;
				lock (locker)
				{
					while (this._taskQueue.Count == 0)
					{
						Monitor.Wait(this._locker);
					}
					t = this._taskQueue.Dequeue();
				}
				if (t == null)
				{
					break;
				}
				this._dequeueAction(t);
			}
		}

		// Token: 0x06000813 RID: 2067 RVA: 0x0002F9E8 File Offset: 0x0002DBE8
		public void Dispose()
		{
			this._workers.ForEach(delegate(Thread thread)
			{
				this.EnqueueTask((T)((object)null));
			});
			this._workers.ForEach(delegate(Thread thread)
			{
				thread.Join();
			});
		}

		// Token: 0x04000801 RID: 2049
		protected readonly object _locker = new object();

		// Token: 0x04000802 RID: 2050
		protected List<Thread> _workers;

		// Token: 0x04000803 RID: 2051
		protected readonly Queue<T> _taskQueue = new Queue<T>();

		// Token: 0x04000804 RID: 2052
		protected readonly Action<T> _dequeueAction;
	}
}
